/*
A sprite polygonal contour extractor.
Copyright (C) 2009-2010  Julien CLEMENT (andematunum@gmail.com)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef sprite_contour_h
#define sprite_contour_h

/**
  * @author (c) 2010, Julien CLEMENT
  * @brief Extract the polygonal contour of a sprite
  * drawn on a transparent background.
  * @details
  * The input image is provided as a pointer to the
  * pixels.
  * The image size is specified as a Point2d with
  * field 'x' as width and field 'y' as height.
  * The image format must be specified with the
  * 'bits_per_pixel' parameter. The value must be
  * one of 8,16,32.
  * The transparent color must be specified with the
  * 'colorkey' parameter.
  * The orientation of the output polygon is given
  * with the 'orientation' boolean parameter, true
  * beeing clockwise and false counter clockwise.
  * The output polygon is given as an ordered list
  * of 2d points. Memory is allocated on the heap
  * and must be explicitly liberated by the caller.
  *
  * On error, the output list is empty.
  *
  * The parallelized versions are made with OpenMP.
  *
  * The algorithm is an original technic found by the
  * author, inspired by the Jarvis progression, and
  * called 'Micro Jarvis progression'. The main difference
  * is that the point set must be connected.
  *
  */

#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <list>

namespace SpriteContourExtractor {
using namespace std;

struct Point2d {
  uint16_t x;
  uint16_t y;
  Point2d(uint16_t xx, uint16_t yy)
    : x(xx), y(yy) {
  }
	Point2d(const Point2d& other) {
		x = other.x;
		y = other.y;
	}
	Point2d& operator= (const Point2d& other) {
		x = other.x;
		y = other.y;
		return *this;
	}
	bool operator== (const Point2d& other) {
		return (x == other.x) && (y == other.y);
	}
};
/**
  * Extract the polygonal contour.
  * The output polygon may be convex or not.
  * This version is non-parallelized.
  */
void extract_contour (const void* pixels,
                      const Point2d& size,
                      uint8_t bits_per_pixel,
                      uint32_t colorkey,
                      bool orientation,
                      list<Point2d*>& contour);
/**
  * Extract the polygonal contour.
  * The output polygon is convex.
  * This version is non-parallelized.
  */
void extract_contour_convex (const void* pixels,
                             const Point2d& size,
                             uint8_t bits_per_pixel,
                             uint32_t colorkey,
                             bool orientation,
                             list<Point2d*>& contour);

#ifdef _OPENMP
#include <omp.h>
/**
  * Extract the polygonal contour.
  * The output polygon may be convex or not.
  * This version is parallelized with OpenMP.
  */
void extract_contour_omp (const void* pixels,
                          const Point2d& size,
                          uint8_t bits_per_pixel,
                          uint32_t colorkey,
                          bool orientation,
                          list<Point2d*>& contour);
/**
  * Extract the polygonal contour.
  * The output polygon is convex.
  * This version is parallelized with OpenMP.
  */
void extract_contour_convex_omp (const void* pixels,
                                 const Point2d& size,
                                 uint8_t bits_per_pixel,
                                 uint32_t colorkey,
                                 bool orientation,
                                 list<Point2d*>& contour);
#endif

} // End namespace

#endif

